package cn.edu.seu.java.ast.visitor;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;

import cn.edu.seu.java.node.ASTClass;

import cn.edu.seu.java.node.ASTEnum;
import cn.edu.seu.java.util.ASTNodeUtil;

/**
* 
* extract classes including top-level class, member class, but except enum class and 
* local class located in a statement (e.g., method, if-statement)
* 
*/
public class ASTClassVisitor {
	private List<ASTClass> listOfASTClass;
	private CompilationUnit unitNode;
	private String packageName;
	private List<ASTClass> listOfTopASTClass;

	public ASTClassVisitor(CompilationUnit node) {
		this.listOfASTClass = new ArrayList<ASTClass>();
		this.listOfTopASTClass = new ArrayList<ASTClass>();
		this.packageName = (String) node.getProperty("packageName");
		this.unitNode = node;
		JavaASTClassVisitor visitor = new JavaASTClassVisitor();
		node.accept(visitor);
	}

	private class JavaASTClassVisitor extends ASTVisitor {
		/**
		* extract classes including top-level class, member class, but except enum class and 
		* local class enclosed within a method or statement
		*/
		public boolean visit(TypeDeclaration node) {
			if (node.isLocalTypeDeclaration() != true) {

				String projectName = (String) unitNode.getProperty("projectName");
				String versionNum = (String) unitNode.getProperty("versionNum");
				String versionPath = (String) unitNode.getProperty("versionPath");
				String sourceFilePath = (String) unitNode.getProperty("sourceFilePath");
				String relativeSourceFilePath = (String) unitNode.getProperty("relativeSourceFilePath");
				String packageName = (String) unitNode.getProperty("packageName");

				ASTClass classNode = new ASTClass(sourceFilePath, node);
				classNode.setProjectName(projectName);
				classNode.setVersionNum(versionNum);
				classNode.setVersionPath(versionPath);
				classNode.setPackageName(packageName);
				classNode.setUnitName(new File(sourceFilePath).getName().replace(".java", ""));
				classNode.setRelativeSourcePath(relativeSourceFilePath);
				listOfASTClass.add(classNode);
			}
			return true;
		}
	}

	/**
	* extract classes including top-level class, member class, but except enum class and 
	* local class enclosed within a method or statement
	*/
	public List<ASTClass> getListOfASTClass() {
		return listOfASTClass;
	}

	public List<ASTClass> getListOfTopASTClass() {
		return listOfTopASTClass;
	}
}
